﻿using System;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x020001B9 RID: 441
	public class HitReactionVRIK : OffsetModifierVRIK
	{
		// Token: 0x06000926 RID: 2342 RVA: 0x00032078 File Offset: 0x00030478
		protected override void OnModifyOffset()
		{
			foreach (HitReactionVRIK.PositionOffset positionOffset in this.positionOffsets)
			{
				positionOffset.Apply(this.ik, this.offsetCurves, this.weight);
			}
			foreach (HitReactionVRIK.RotationOffset rotationOffset in this.rotationOffsets)
			{
				rotationOffset.Apply(this.ik, this.offsetCurves, this.weight);
			}
		}

		// Token: 0x06000927 RID: 2343 RVA: 0x000320FC File Offset: 0x000304FC
		public void Hit(Collider collider, Vector3 force, Vector3 point)
		{
			if (this.ik == null)
			{
				Debug.LogError("No IK assigned in HitReaction");
				return;
			}
			foreach (HitReactionVRIK.PositionOffset positionOffset in this.positionOffsets)
			{
				if (positionOffset.collider == collider)
				{
					positionOffset.Hit(force, this.offsetCurves, point);
				}
			}
			foreach (HitReactionVRIK.RotationOffset rotationOffset in this.rotationOffsets)
			{
				if (rotationOffset.collider == collider)
				{
					rotationOffset.Hit(force, this.offsetCurves, point);
				}
			}
		}

		// Token: 0x040005D8 RID: 1496
		public AnimationCurve[] offsetCurves;

		// Token: 0x040005D9 RID: 1497
		[Tooltip("Hit points for the FBBIK effectors")]
		public HitReactionVRIK.PositionOffset[] positionOffsets;

		// Token: 0x040005DA RID: 1498
		[Tooltip(" Hit points for bones without an effector, such as the head")]
		public HitReactionVRIK.RotationOffset[] rotationOffsets;

		// Token: 0x020001BA RID: 442
		[Serializable]
		public abstract class Offset
		{
			// Token: 0x170000B5 RID: 181
			// (get) Token: 0x0600090A RID: 2314 RVA: 0x0003195C File Offset: 0x0002FD5C
			// (set) Token: 0x0600090B RID: 2315 RVA: 0x00031964 File Offset: 0x0002FD64
			public float crossFader;

			// Token: 0x170000B6 RID: 182
			// (get) Token: 0x0600090C RID: 2316 RVA: 0x0003196D File Offset: 0x0002FD6D
			// (set) Token: 0x0600090D RID: 2317 RVA: 0x00031975 File Offset: 0x0002FD75
			public float timer;

			// Token: 0x170000B7 RID: 183
			// (get) Token: 0x0600090E RID: 2318 RVA: 0x0003197E File Offset: 0x0002FD7E
			// (set) Token: 0x0600090F RID: 2319 RVA: 0x00031986 File Offset: 0x0002FD86
			public Vector3 force;

			// Token: 0x170000B8 RID: 184
			// (get) Token: 0x06000910 RID: 2320 RVA: 0x0003198F File Offset: 0x0002FD8F
			// (set) Token: 0x06000911 RID: 2321 RVA: 0x00031997 File Offset: 0x0002FD97
			public Vector3 point;

			// Token: 0x06000931 RID: 2353 RVA: 0x00032200 File Offset: 0x00030600
			public void Hit(Vector3 force, AnimationCurve[] curves, Vector3 point)
			{
				if (this.length == 0f)
				{
					this.length = this.GetLength(curves);
				}
				if (this.length <= 0f)
				{
					Debug.LogError("Hit Point WeightCurve length is zero.");
					return;
				}
				if (this.timer < 1f)
				{
					this.crossFader = 0f;
				}
				this.crossFadeSpeed = ((this.crossFadeTime <= 0f) ? 0f : (1f / this.crossFadeTime));
				this.CrossFadeStart();
				this.timer = 0f;
				this.force = force;
				this.point = point;
			}

			// Token: 0x06000932 RID: 2354 RVA: 0x000322AC File Offset: 0x000306AC
			public void Apply(VRIK ik, AnimationCurve[] curves, float weight)
			{
				float num = Time.time - this.lastTime;
				this.lastTime = Time.time;
				if (this.timer >= this.length)
				{
					return;
				}
				this.timer = Mathf.Clamp(this.timer + num, 0f, this.length);
				if (this.crossFadeSpeed > 0f)
				{
					this.crossFader = Mathf.Clamp(this.crossFader + num * this.crossFadeSpeed, 0f, 1f);
				}
				else
				{
					this.crossFader = 1f;
				}
				this.OnApply(ik, curves, weight);
			}

			// Token: 0x06000933 RID: 2355
			protected abstract float GetLength(AnimationCurve[] curves);

			// Token: 0x06000934 RID: 2356
			protected abstract void CrossFadeStart();

			// Token: 0x06000935 RID: 2357
			protected abstract void OnApply(VRIK ik, AnimationCurve[] curves, float weight);

			// Token: 0x040005DB RID: 1499
			[Tooltip("Just for visual clarity, not used at all")]
			public string name;

			// Token: 0x040005DC RID: 1500
			[Tooltip("Linking this hit point to a collider")]
			public Collider collider;

			// Token: 0x040005DD RID: 1501
			[Tooltip("Only used if this hit point gets hit when already processing another hit")]
			[SerializeField]
			private float crossFadeTime = 0.1f;

			// Token: 0x040005E2 RID: 1506
			private float length;

			// Token: 0x040005E3 RID: 1507
			private float crossFadeSpeed;

			// Token: 0x040005E4 RID: 1508
			private float lastTime;
		}

		// Token: 0x020001BB RID: 443
		[Serializable]
		public class PositionOffset : HitReactionVRIK.Offset
		{
			// Token: 0x06000937 RID: 2359 RVA: 0x00032360 File Offset: 0x00030760
			protected override float GetLength(AnimationCurve[] curves)
			{
				float num = (curves[this.forceDirCurveIndex].keys.Length <= 0) ? 0f : curves[this.forceDirCurveIndex].keys[curves[this.forceDirCurveIndex].length - 1].time;
				float min = (curves[this.upDirCurveIndex].keys.Length <= 0) ? 0f : curves[this.upDirCurveIndex].keys[curves[this.upDirCurveIndex].length - 1].time;
				return Mathf.Clamp(num, min, num);
			}

			// Token: 0x06000938 RID: 2360 RVA: 0x00032404 File Offset: 0x00030804
			protected override void CrossFadeStart()
			{
				foreach (HitReactionVRIK.PositionOffset.PositionOffsetLink positionOffsetLink in this.offsetLinks)
				{
					positionOffsetLink.CrossFadeStart();
				}
			}

			// Token: 0x06000939 RID: 2361 RVA: 0x00032438 File Offset: 0x00030838
			protected override void OnApply(VRIK ik, AnimationCurve[] curves, float weight)
			{
				Vector3 a = ik.transform.up * base.force.magnitude;
				Vector3 vector = curves[this.forceDirCurveIndex].Evaluate(base.timer) * base.force + curves[this.upDirCurveIndex].Evaluate(base.timer) * a;
				vector *= weight;
				foreach (HitReactionVRIK.PositionOffset.PositionOffsetLink positionOffsetLink in this.offsetLinks)
				{
					positionOffsetLink.Apply(ik, vector, base.crossFader);
				}
			}

			// Token: 0x040005E5 RID: 1509
			[Tooltip("Offset magnitude in the direction of the hit force")]
			public int forceDirCurveIndex;

			// Token: 0x040005E6 RID: 1510
			[Tooltip("Offset magnitude in the direction of character.up")]
			public int upDirCurveIndex = 1;

			// Token: 0x040005E7 RID: 1511
			[Tooltip("Linking this offset to the VRIK position offsets")]
			public HitReactionVRIK.PositionOffset.PositionOffsetLink[] offsetLinks;

			// Token: 0x020001BC RID: 444
			[Serializable]
			public class PositionOffsetLink
			{
				// Token: 0x0600093B RID: 2363 RVA: 0x000324E6 File Offset: 0x000308E6
				public void Apply(VRIK ik, Vector3 offset, float crossFader)
				{
					this.current = Vector3.Lerp(this.lastValue, offset * this.weight, crossFader);
					ik.solver.AddPositionOffset(this.positionOffset, this.current);
				}

				// Token: 0x0600093C RID: 2364 RVA: 0x0003251D File Offset: 0x0003091D
				public void CrossFadeStart()
				{
					this.lastValue = this.current;
				}

				// Token: 0x040005E8 RID: 1512
				[Tooltip("The FBBIK effector type")]
				public IKSolverVR.PositionOffset positionOffset;

				// Token: 0x040005E9 RID: 1513
				[Tooltip("The weight of this effector (could also be negative)")]
				public float weight;

				// Token: 0x040005EA RID: 1514
				private Vector3 lastValue;

				// Token: 0x040005EB RID: 1515
				private Vector3 current;
			}
		}

		// Token: 0x020001BD RID: 445
		[Serializable]
		public class RotationOffset : HitReactionVRIK.Offset
		{
			// Token: 0x0600093E RID: 2366 RVA: 0x00032534 File Offset: 0x00030934
			protected override float GetLength(AnimationCurve[] curves)
			{
				return (curves[this.curveIndex].keys.Length <= 0) ? 0f : curves[this.curveIndex].keys[curves[this.curveIndex].length - 1].time;
			}

			// Token: 0x0600093F RID: 2367 RVA: 0x00032588 File Offset: 0x00030988
			protected override void CrossFadeStart()
			{
				foreach (HitReactionVRIK.RotationOffset.RotationOffsetLink rotationOffsetLink in this.offsetLinks)
				{
					rotationOffsetLink.CrossFadeStart();
				}
			}

			// Token: 0x06000940 RID: 2368 RVA: 0x000325BC File Offset: 0x000309BC
			protected override void OnApply(VRIK ik, AnimationCurve[] curves, float weight)
			{
				if (this.collider == null)
				{
					Debug.LogError("No collider assigned for a HitPointBone in the HitReaction component.");
					return;
				}
				if (this.rigidbody == null)
				{
					this.rigidbody = this.collider.GetComponent<Rigidbody>();
				}
				if (this.rigidbody != null)
				{
					Vector3 axis = Vector3.Cross(base.force, base.point - this.rigidbody.worldCenterOfMass);
					float angle = curves[this.curveIndex].Evaluate(base.timer) * weight;
					Quaternion offset = Quaternion.AngleAxis(angle, axis);
					foreach (HitReactionVRIK.RotationOffset.RotationOffsetLink rotationOffsetLink in this.offsetLinks)
					{
						rotationOffsetLink.Apply(ik, offset, base.crossFader);
					}
				}
			}

			// Token: 0x040005EC RID: 1516
			[Tooltip("The angle to rotate the bone around it's rigidbody's world center of mass")]
			public int curveIndex;

			// Token: 0x040005ED RID: 1517
			[Tooltip("Linking this hit point to bone(s)")]
			public HitReactionVRIK.RotationOffset.RotationOffsetLink[] offsetLinks;

			// Token: 0x040005EE RID: 1518
			private Rigidbody rigidbody;

			// Token: 0x020001BE RID: 446
			[Serializable]
			public class RotationOffsetLink
			{
				// Token: 0x06000942 RID: 2370 RVA: 0x000326AB File Offset: 0x00030AAB
				public void Apply(VRIK ik, Quaternion offset, float crossFader)
				{
					this.current = Quaternion.Lerp(this.lastValue, Quaternion.Lerp(Quaternion.identity, offset, this.weight), crossFader);
					ik.solver.AddRotationOffset(this.rotationOffset, this.current);
				}

				// Token: 0x06000943 RID: 2371 RVA: 0x000326E7 File Offset: 0x00030AE7
				public void CrossFadeStart()
				{
					this.lastValue = this.current;
				}

				// Token: 0x040005EF RID: 1519
				[Tooltip("Reference to the bone that this hit point rotates")]
				public IKSolverVR.RotationOffset rotationOffset;

				// Token: 0x040005F0 RID: 1520
				[Tooltip("Weight of rotating the bone")]
				[Range(0f, 1f)]
				public float weight;

				// Token: 0x040005F1 RID: 1521
				private Quaternion lastValue = Quaternion.identity;

				// Token: 0x040005F2 RID: 1522
				private Quaternion current = Quaternion.identity;
			}
		}
	}
}
